package com.jeesite.modules.dataScreen.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeesite.modules.dataScreen.dao.EventOrderDao;
import com.jeesite.modules.dataScreen.entity.EventOrder;
import com.jeesite.modules.dataScreen.entity.EventOrderProcess;
import com.jeesite.modules.dataScreen.enums.SourceSystemCodeEnum;
import com.jeesite.modules.dataScreen.utils.MyDateUtils;
import com.jeesite.modules.dataScreen.web.dto.EventOrderDTO;
import com.jeesite.modules.dataScreen.web.dto.UrbanMovementDto;
import com.jeesite.modules.dataScreen.web.vo.EventOrderProcessVo;
import com.jeesite.modules.dataScreen.web.vo.UrbanMovementDetailVo;
import com.jeesite.modules.dataScreen.web.vo.UrbanMovementVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author machenzhi
 * @date 2024/08/08 10:17
 */
@Service
@Slf4j
public class EventOrderService extends ServiceImpl<EventOrderDao, EventOrder> {

    @Resource
    private EventOrderProcessService eventOrderProcessService;

    public synchronized void add(EventOrderDTO dto) {

        String sourceSystemCode = dto.getSourceSystemCode();
        SourceSystemCodeEnum anEnum = SourceSystemCodeEnum.getEnum(sourceSystemCode);
        if (Objects.isNull(anEnum)) {
            log.error("应用识别码不存在 dto:{}", JSON.toJSONString(dto));
            throw new IllegalArgumentException("应用识别码不存在");
        }

        Optional.ofNullable(getByEventNum(dto.getEventNum(), sourceSystemCode))
                .ifPresent(o -> {
                    log.error("事件已存在 dto:{}", JSON.toJSONString(dto));
                    throw new IllegalArgumentException("事件已存在");
                });


        EventOrder eventOrder = new EventOrder();
        BeanUtils.copyProperties(dto, eventOrder);
        //默认为未结案，根据处置确认状态
        eventOrder.setEndStatus("0");
        this.save(eventOrder);
    }

    /**
     * 修改状态为已完成
     *
     * @param eventNum
     */
    public void modifyEndStatus(String eventNum) {
        LambdaUpdateWrapper<EventOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(EventOrder::getEventNum, eventNum);
        updateWrapper.set(EventOrder::getEndStatus, "1");
        this.update(updateWrapper);
    }


    public EventOrder getByEventNum(String eventNum, String sourceSystemCode) {
        LambdaQueryWrapper<EventOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EventOrder::getEventNum, eventNum)
                .eq(EventOrder::getSourceSystemCode, sourceSystemCode);
        return this.getOne(queryWrapper);
    }

    public IPage<UrbanMovementVo> list(UrbanMovementDto dto) {
        IPage<UrbanMovementVo> page = new Page<>();
        page.setCurrent(dto.getPageNum()).setSize(dto.getPageSize());
        String keywords = dto.getKeywords();
        if (StrUtil.isNotBlank(keywords)) {
            Date[] times = MyDateUtils.lately(keywords);
            dto.setStart(times[0]);
            dto.setEnd(times[1]);
        }

        IPage<UrbanMovementVo> list = getBaseMapper().list(page, dto);
        for (UrbanMovementVo movementVo : list.getRecords()) {
            movementVo.assemblyLevel();
            movementVo.setSourceSystemCode(SourceSystemCodeEnum.getText(movementVo.getSourceSystemCode()));
        }
        return list;
    }

    public List<EventOrderProcessVo> detailList(String eventNum) {
        List<EventOrderProcessVo> result = new ArrayList<>();
        LambdaQueryWrapper<EventOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EventOrder::getEventNum, eventNum);
        EventOrder eventOrder = getOne(queryWrapper);
        if (Objects.nonNull(eventOrder)) {

            List<EventOrderProcess> processes = eventOrderProcessService.list(eventNum, eventOrder.getSourceSystemCode());
            if (CollUtil.isNotEmpty(processes)) {
                processes.sort(Comparator.comparing(EventOrderProcess::getExecuteTime));
            }
            EventOrderProcessVo vo;
            EventOrderProcess process;
            for (int i = 0; i < processes.size(); i++) {
                process = processes.get(i);
                vo = new EventOrderProcessVo();
                vo.setLat(eventOrder.getLat());
                vo.setLon(eventOrder.getLon());
                vo.setDescribe(process.getExecuteContent());
                vo.setPlace(process.getExecuteDept());
                vo.setTitle(eventOrder.getEventTitle());
                vo.setStatus("处置中");
                vo.setHappenTime(process.getExecuteTime());
                if (i == 0) {
                    vo.setStatus("发生");
                } else if ((process == CollUtil.getLast(processes))
                        && "1".equals(process.getEndStatus())) {
                    vo.setStatus("完结");
                }
                result.add(vo);
            }
            eventOrder.setSourceSystemCode(SourceSystemCodeEnum.getText(eventOrder.getSourceSystemCode()));
        }
        return result;
    }

    public UrbanMovementDetailVo detail(String eventNum) {
        UrbanMovementDetailVo result = new UrbanMovementDetailVo();
        LambdaQueryWrapper<EventOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EventOrder::getEventNum, eventNum);
        EventOrder eventOrder = getOne(queryWrapper);
        result.setEventOrder(eventOrder);
        result.setStatus("0");
        if (Objects.nonNull(eventOrder)) {
            List<EventOrderProcess> processes = eventOrderProcessService.list(eventOrder.getEventNum(), eventOrder.getSourceSystemCode());
            if (CollUtil.isNotEmpty(processes)) {
                processes.sort(Comparator.comparing(EventOrderProcess::getExecuteTime));
                String endStatus = processes.get(processes.size() - 1).getEndStatus();
                result.setStatus(endStatus);
            }
            result.setProcesses(processes);
            eventOrder.setSourceSystemCode(SourceSystemCodeEnum.getText(eventOrder.getSourceSystemCode()));
        }
        return result;
    }

    public JSONObject eventOrderCount(String keywords) {
        Date[] times = null;
        if (StrUtil.isNotBlank(keywords)) {
            times = MyDateUtils.lately(keywords);
        }
        return getBaseMapper().getEventOrderCount(times);
    }

    public JSONObject levelCount() {
        return getBaseMapper().getLevelCount();
    }
}
